RiverSync
SPEC-UX-TKT · v1.0
29 June 2026
Owner: Platform team

Design specification · build-ready · Support · Tickets

The ticket communication system — one support conversation, three apps

The exhaustive design specification for RiverSync's multi-party support conversation: the surface a customer uses to talk to the RiverSync service desk, the agent uses to work every tenant's tickets, and a servicing partner uses once they are brought onto a unit. It is specified as one reusable component — the same layout, command bar, thread and composer, reskinned per app by a single viewer setting — so Portal, Admin and Partners never diverge. Written so an implementer needs no further decisions: each region, state, class, icon and viewer rule is named.

Prototyped Design spec · v1.0 Reusable across 3 apps
This is a design view over a settled model. The requirement is SPEC-APP-PTL PTL-4 (tickets are a multi-party support conversation), reused by SPEC-APP-PAR and SPEC-APP-ADM; the entities ServiceTicket · TicketMessage live in the Portal ERD; the events & service in the Support domain; the process in SPEC-PWF-INC and the lifecycle in SPEC-DWF-SUP. This document owns no model — it specifies how that model is presented and operated, and the rules for reusing the one surface across apps. On any conflict the platform master wins. Prototype of record: the shared engine apps/portal/portal-tickets.jsx (exposed as PV.Tickets) and mounter apps/portal/ticket-app.jsx, deployed as a dedicated page in each app — customer in apps/portal/Portal.html, RiverSync agent in apps/account/Admin Tickets.html, servicing partner in apps/partners/Partner Tickets.html.

1What it is — and what it is not

The ticket communication system is a multi-party support conversation about one device. The customer opens a ticket (often from an alarm) and talks to the RiverSync service desk first line; RiverSync brings a servicing partner onto the thread when a unit's maintenance agreement makes them relevant. Every party works the same conversation — only what they may see and do changes.

It is
  • The customer↔RiverSync↔partner support thread, anchored to a DeviceId and a ServiceTicket.
  • One reusable surface (PV.Tickets) reskinned by viewercustomer (Portal), agent (Admin), partner (Partners).
  • Rich: device alert/alarm cards, file & picture attachments, shared artifacts, in-thread visit scheduling.
  • Operationally aware: internal notes, quick replies, read receipts, presence and a live typing signal.
It is not
  • The Pipeline sales inbox — that is Communications (Conversation, RiverSync-internal, channel folders). Different system, different surface.
  • A second source of truth for the device, alarm or agreement — it links to them; they stay canonical.
  • A generic chat room — every thread is one ticket with a status, priority, category and SLA.

2The shape at a glance

One immersive page: a full-width context-aware command bar, then a list → thread → context-rail body that fills the height. The conversation parties are always customer + RiverSync, plus a partner once brought in. The surface is identical across the three apps; the differences are entirely captured by viewer.

3 viewers customeragentpartner
ticket status openin-progressresolved
message kinds replyinternal noteeventalert cardattachmentappointment

The five W's of every ticket are visible in the list row before it is opened — who (the other parties' avatars + names), about what (subject + category), which device (id + status dot), when (last activity), what state (status badge + unread dot).

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 1

3One surface, three viewers

The component takes a single viewer prop. Everything app-specific — the shell chrome (App pill, nav, tenant), which parties are shown as "the others", the composer affordances and what is hidden — derives from it. There is no forked code per app, and no in-app "view as" switcher — each app deploys its own viewer-locked page through the shared mounter, so a customer only ever sees the customer view (in the Portal app), an agent the agent view (in Admin), a partner the partner view (in Partners).

viewerApp / pillSigned-in partyWhat this viewer can do
customerPortal · --portalCustomer (Sanyodenki)Open tickets from an alarm/device, reply to RiverSync (and the partner once present), request a partner on site, mark resolved. Never sees internal notes.
agentAdmin · --adminRiverSync service deskWorks every tenant's tickets. Reply / internal note toggle, quick replies, bring in a servicing partner, schedule a visit, resolve/reopen. Sees everything.
partnerPartners · --partnersServicing partner (Nera)Sees only tickets they have been brought onto, scoped to their devices. Replies to RiverSync & the customer. Never sees RiverSync internal notes.
ReuseThe viewer maps to one internal "kind". agent→riversync, partner→partner, else customer. The kind drives three things only: (1) which parties render as "the others" in the list & participant strip; (2) the composer (note toggle + quick replies are riversync-only); (3) note visibility — an internal note is dropped from the thread for any non-riversync viewer. Same data, same component.
ScopeThe partner list is pre-scoped. A partner viewer only ever sees tickets whose partner is set (i.e. they were brought in) — enforced before the status filter, so "Open / All / Resolved" count within their own scope. The customer and agent see the full set for their tenant context.

3.1Bringing a partner in

A ticket starts as customer↔RiverSync. RiverSync (or, on request, the customer) brings a servicing partner onto the thread when the device's active maintenance agreement names one. This is a first-class event, not a re-route.

V-1

Agent brings in. The command bar / participant strip Bring in partner resolves the partner from agreementFor(device).active.partner, sets the ticket's partner, and writes a system event "RiverSync brought in {Partner} — servicing partner".

V-2

Customer requests. The same control for a customer reads Request partner and raises a request to RiverSync (toast); only RiverSync sets the partner.

V-3

Partner can't add a partner. The control is hidden for the partner viewer (they are the partner).

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 2

4The data the surface renders

The UI never invents fields. Every rendered value maps to the ServiceTicket + TicketMessage model owned by the Support domain and defined in SPEC-ERD-PTL. Field names below are the presentation contract the prototype reads.

ServiceTicketsupport thread · TKT-NNNN
FieldKeyMeaning & UI use
IdPKTKT-NNNN — list-row key, command-bar id, thread anchor.
DeviceIdFK→ Device. The ticket is always about one device; drives the device chip, rail, status dot.
CustomerIdFK→ the owning customer organization (a conversation party).
PartnerIdFK→ servicing partner · 0..1. Null until brought in; presence adds the third party (V-1).
SubjectThread title — list row + thread header.
Statusopenin-progressresolved — status badge; resolved locks the composer.
Priorityhighmediumlow — priority badge (danger / warning / neutral).
Categoryincidentmaintenancefirmwarequestion — the category chip + icon.
FromAlertIdFK→ Alert · 0..1 — the origin alarm; renders the Alarm linked chip + rail origin.
OpenedAt · SlaOpened date + SLA line (e.g. "Awaiting first response") in the thread sub-header.
LastActivityAt+ Unread — list timestamp and the unread dot / bold weight.
TicketMessageper ticket · ordered
FieldKeyMeaning & UI use
TicketIdPFParent thread.
AuthorPartycustomerriversyncpartner + author name. Determines bubble side per viewer (mine = right).
BodyMarkdown / text — rendered injection-safe by ChatMarkdown.
NoteBoolean — an internal note: visible to riversync only; dashed warning bubble.
Time · StatePer-message time + delivery state sendingsentdeliveredread (§9.3).
Attachmentsfiles · pictures · 0..n — each renders a FileAttachment / ImageSet card under the bubble.
Alert · Slots · Appointment · ArtifactOptional embedded cards — device alert/alarm, a slot proposal, a confirmed visit, a shared .md.
Kinddayeventunread — non-message thread rows (divider · system event · unread marker).
NoteInternal notes are a visibility rule, not a separate store. A TicketMessage with Note=true is the same record; the surface simply omits it from the thread for any viewer whose kind is not riversync. Never deliver note bodies to a customer or partner client.
RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 3

5Layout & grid

Below the shell chrome the page is a vertical stack: a full-width command bar, then a body grid that fills the remaining height — a fixed conversation list, the thread, and an optional context rail. Each column scrolls independently; the page itself does not scroll.

Tickets 4 open · view MDC-2044 Bring in partner Resolve Search… Reply Open · All · Resolved device alarm card Reply · Internal note Quick replies DEVICE MAINTENANCE AGREEMENT PARTICIPANTS 1 2 3 4 5 6 7
Ticket surface anatomy (reference layout, not to absolute scale). Numbered regions are specified below.
RegionSizingSpecification
1Command bar .pv-cmdbarfull width · 40pxFixed at the top — the one chrome that never scrolls (height 40px, matching the shell top bar). Left: identity tile (Tickets + open-count + viewer label). Middle: context commands (hairline-divided). Right: search + primary Reply.
2List column .pv-tk__list340pxTools row (filter segment + count) pinned over an independently scrolling stack of ticket rows — the scrollbar is hidden (scrollbar-width:none) for a clean rail.
3Category chip .pv-tkcatautoThe ticket's category (incident / maintenance / firmware / question) with icon + tone, atop the subject.
4Participant strip .pv-tkpartyautoThe other parties as avatar pills with presence; a dashed Bring in / Request partner chip when none.
5Detail scroll .pv-tkscrollfills · scrollsThe center scrolls as one region — the ticket header scrolls with the thread (only the command bar and composer stay fixed). Holds the header then the ChatThread (messages ascending; mine right, others left; cards under bubbles; day / event / unread / typing rows). Auto-scrolls to newest on open & send.
6Composer .pv-tkcompauto · pinnedControl row (mode toggle / visibility + quick replies) over the DS ChatComposer; locked note when resolved.
7Context rail .pv-tk__rail300px / 40pxTwo states, toggled from the rail. Details (full — device, maintenance agreement, participants, origin) at 300px; and a minimized icon-rail glance at 40px — the collapsed left-sidebar width. At 40px every fact becomes one icon with a hover tooltip and tap-to-act: a tinted status glyph, a priority dot, the device, SLA, the agreement tier+partner, the origin alarm, then the participant avatars stacked. State persists in localStorage. Hidden under 1180px and in split layout.

Grid: .pv-tk{display:grid; grid-template-columns:340px 1fr;}; .pv-tk--rail{…340px 1fr 300px;}. The page is immersive (.pv-tkpage--immersive): no page padding, fills below the 40px top bar. The center column is a single scroller (.pv-tkscroll) carrying header + thread; the command bar (40px) and composer are the only fixed chrome. Under 900px the list collapses and the thread takes over (master-detail) — see §11 responsive.

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 4

6The command bar

Adapted from the pipeline communications navbar: a full-width, square, hairline-divided strip of commands. It is context-aware — the commands depend on the selected ticket, its status and the viewer. The primary action sits at the right with search; when nothing is selected the middle shows the hint "Select a ticket to act on it."

CommandIcon · styleShown forBehavior
DeviceserverallOpens the linked device. Label is the device id (e.g. MDC-2044).
Bring in partnerhubagent · no partnerResolves & sets the servicing partner; writes the bring-in event (V-1).
Request partnerhubcustomer · no partnerRaises a request to RiverSync (toast) (V-2).
Schedule visitcalendaragent · openOpens the slot proposer for the servicing partner.
Resolvesuccess · okall · openSets status=resolved; writes a resolve event; locks the composer.
Reopenrefreshall · resolvedSets status=open; writes a reopen event; unlocks the composer.
Mark unreademail · iconallRe-flags the selected ticket unread without leaving it.
Replycorner-down-left · primaryall · openRight edge. Focuses the composer textarea. No toast.
MirrorThe thread header keeps an overflow more-horizontal menu that mirrors the bar (Open device · Bring in / Request partner · Mark unread · Resolve / Reopen) so every action is reachable from the reader too. On narrow widths the command labels collapse to icons (the bar never wraps).

6.1The list & row

The left column is a pinned tools row (the Open / All / Resolved segment + an N shown count) over scrolling rows. One row is selected at a time and reflected in the thread.

ElementSpec
Party avatarsUp to two overlapping 30px rs-av tiles — the other parties (presence dot when online). Two-initial, DS palette (rs-av-c0…c5).
Who + timeTop line: the other parties' short names joined by ·; a paperclip when the thread has attachments; relative time.
Subject + previewTwo-line subject (bold when unread) + one-line preview of the latest message.
FootMono ticket id · device id with a status dot · the status badge (DS Badge, right-aligned).
Unread · selectedis-unread → accent dot + bold subject; is-active → accent-soft fill + 3px left bar. Selecting clears unread.
RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 5

7The thread & its parties

The reader is a single scrolling region: a header that scrolls away with the conversation — a compact, horizontal two-row composition (row 1: category · subject · id/opened/SLA on the left, status & priority badges + actions on the right; row 2: the participant strip and the linked-context chips side by side) — then the thread. Only the command bar and the composer stay fixed. The thread is the DS ChatThread; messages map to its items.

RegionSpecification
Header sub-lineStatus badge + priority badge + mono id + opened date + SLA (clock) — the facts of the ticket.
Participant strip .pv-tkpartyOne pill per other party: 26px avatar (presence dot), short org name + role line ("Service desk · first line" / "Servicing partner" / "Customer", with · online when present). RiverSync's pill carries the accent tint.
Linked chips .pv-tklinksLinked + a chip per related record: Device (always), Alarm (when from an alert, danger tone), Gold/Silver agreement (maintenance tone) → the partner. Each deep-links.
Message bubbleMine = right (accent-soft), others = left (--surface-2). Avatar + name (others carry · {org}) + time; markdown body; cards beneath.
Cards under a bubbleChatAlertCard (device alert/alarm) · ImageSet / FileAttachment · ArtifactCard (shared .md) · SlotPickerAppointmentCard (visit).
System rowsday divider · event row (ticket opened / resolved / partner brought in) · unread marker.
PartiesThe thread always renders the OTHER parties to the viewer. Parties are customer + RiverSync (+ partner when present); the viewer's own party is filtered out of the strip and their own messages render as "mine" on the right. So the same thread reads correctly from all three apps with no per-app markup.

7.1Avatars — the pipeline idiom

Avatars are the two-initial rs-av tiles from the communications system (square 2px, DS palette rs-av-c0…c5), sized via --s: 30px in list rows (overlapping −10px with a surface ring), 26px in the strip, 28px in the rail, sm in bubbles. Presence is the DS corner dot (rs-av__status online). This replaces the former single-letter circular avatar so every surface — list, strip, bubble, rail — reads identically and matches Pipeline.

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 6

8Communicating in the chat area

The composer is the one entry point, and it adapts to the viewer. Around the DS ChatComposer (autosizing textarea, attach with progress, drag-and-drop, markdown preview, Enter-to-send) sits a control row that carries the operational affordances.

CapabilityViewerSpecification
Reply vs internal noteagentA segmented toggle Reply · Internal note. In note mode the placeholder, the visibility line and the sent bubble all switch — the message is stored Note=true and never shown to customer/partner (§4 Note rule). A live visibility line states exactly who can see the next message.
Quick replies (canned)agentA Quick replies popover of curated, sentence-case presets (Acknowledge · Ask for a reading · Dispatching a partner · Confirm before close). Picking one sends it immediately as a normal reply.
AttachmentsallFiles & pictures stage with progress chips (drag-and-drop supported); each posts as a FileAttachment / ImageSet card under the bubble. Images open a lightbox.
Device alert / alarm cardsallA ticket opened from an alarm carries the ChatAlertCard inline (severity tone, alarm ping) with a View deep-link to the alert.
Visit schedulingagentThe composer's calendar tool (reply mode only) proposes visit slots (SlotPicker); a confirmed visit renders an AppointmentCard in-thread.
Visibility linecustomer · partnerAbove the composer: "Visible to {parties}" — so a sender always knows the audience. Resolved tickets show the locked note instead.
NotesInternal notes are RiverSync-only and unmistakable. Only the agent viewer gets the toggle; the note bubble is a dashed warning style with an "Internal note" tag; the visibility line reads "Internal note — visible to RiverSync only, never the customer or partner." Switching the toggle off returns to a customer-visible reply.

8.1Presence & typing

Two live signals keep the conversation feeling staffed.

C-1

Presence. Each participant avatar (strip, list, rail) shows the DS online dot when that party is present — the RiverSync service desk reads · online so a customer knows someone is there.

C-2

Typing. After the viewer sends a reply, a transient ChatTyping row from the responding party appears at the foot of the thread (the service desk for customer/partner; the customer for the agent) and clears after a short beat — the indicator the DS provides, gated to reply (not note) sends and honoring reduced motion.

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 7

9Interactions & states

Every status change and message write runs the same way regardless of which control fired it (command bar, header menu or composer), so behavior is identical across the surface.

ActionResultToast
ReplyAppend message; (reply mode) trigger typing— (no toast)
Internal noteAppend Note=true message (agent)— (no toast)
Quick replySend the chosen preset immediately— (no toast)
Resolvestatus=resolved; resolve event; lock composer"Ticket resolved · TKT status set to Resolved." (success)
Reopenstatus=open; reopen event; unlock"Ticket reopened…" (info)
Bring in partnerSet partner; bring-in event"Partner brought in · {Partner} added to this ticket." (info)
Mark unreadRe-flag the ticket unread"Marked unread…" (info)

9.1Resolved & locked

A resolved ticket replaces the composer with a locked note — "This ticket is resolved. Reopen it to keep talking." The command bar swaps Resolve for Reopen and drops the primary Reply. Reopening restores the open state and the composer.

9.2Empty & no-match

No selection → the thread shows .pv-tk__empty (ticket icon, "Select a ticket"). A filter that matches nothing → .pv-tkrow__none (inbox icon, "No tickets in this view."). Layout reserves its dimensions; the surface never reflows on data arrival (mirrors the charts rule).

9.3Read receipts

Delivery state advances sendingsentdeliveredread with the DS tick (single → double → accent double). Receipts are derived, not hand-set: one of my messages reads as read once any later message from another party exists; the newest unanswered one shows delivered. Receipts show only on my own outgoing messages — never on incoming. A failed send shows a danger state with Retry; it never silently disappears.

Loading

List + thread reserve their dimensions; skeleton rows / quiet placeholder. No reflow when data lands.

Resolved

Composer → locked note; bar → Reopen; thread read-only until reopened.

No partner yet

Participant strip shows the dashed Bring in / Request partner chip (by viewer).

Send error

Optimistic message rolls back to a danger chip with Retry; never dropped.

RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 8

10Design-system mapping

Every element resolves to a RiverSync DS v2 component, class, icon or token. The surface is a React page composing the DS chat layer; the pv-tk* / pv-cmdbar* classes are the Portal-local layer in portal.css, themed entirely through DS tokens.

ElementClass / componentDS basis
App pill (top bar)rs-portalbadge--portal / --admin / --partnersCanonical app badge per viewer (shell-chrome.css). Mandatory.
ShellAppShell (hub / admin) · vanilla shell (partners)The DS shell; the partner pill is re-tinted where AppShell ships no partners config (see §10.1).
ThreadChatThread + ChatMessage / ChatEvent / ChatDay / ChatUnread / ChatTypingDS chat system — bubbles, delivery ticks, typing dots.
ComposerChatComposerDS composer — attach + progress, drag-drop, markdown, schedule hook.
CardsChatAlertCard · FileAttachment · ImageSet · ArtifactCard · SlotPicker · AppointmentCardDS card-under-bubble idiom.
Avatarrs-av rs-av-c0…c5 + rs-av__statusDS avatar tile (square, two-initial) + presence dot.
Status / priorityBadge (tone)DS status badge — 2px radius, soft tint, sentence case.
Command buttonspv-cmd pv-cmd--primary / --ok / --iconCommand-bar buttons over DS tokens (the pipeline pl-cmd idiom).
Segmentsrs-seg rs-seg--smDS segmented control (filter + reply/note toggle).
ToastPVToast(title, msg, kind)Portal toast — success / info / warning.
Icons<Icon name="…"/>Proprietary icon system (the G geometry table) — never a third-party set.

Icons in use: ticket · server · hub · calendar · success · refresh · email · corner-down-left · search · alert · wrench · chevron-right · more-horizontal · paperclip · image · file-text · chat · lock · eye · check · plus · inbox · clock. Any new glyph is added to the DS G table first, never drawn inline.

10.1The partners-badge note

GapThe React AppShell ships portal configs for hub · admin · ops · account but not partners. For the partner viewer the surface re-tints the top-bar App pill to rs-portalbadge--partners (teal, hub glyph, "Partners") to honor the mandatory badge. Proposed: add a first-class partners portal to AppShell (and upstream the partners pill already in riversync-ui.css) so no re-tint is needed.
RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 9

11Reuse rules & responsive

The whole point of this spec is one surface, embedded by every app. These rules keep it that way.

R-1

One engine, embedded per app. The surface is the single component PV.Tickets, mounted through the shared helper PV.mountTicketApp (ticket-app.jsx). Each app deploys its own page (Portal · Admin · Partners); they embed the engine, they do not copy it. A change to the thread, command bar or composer lands once and every app inherits it.

R-2

Configure by props, not forks. An embedding app passes only: viewer, the ticket data + onAddUpdate / onTicketChange handlers, me (signed-in party), go (navigation), toast, and presentation flags (layout · bubbles · density). No app reaches inside the component.

R-3

The shell is the app's, the surface is shared. Each app wraps the surface in its own shell with its own App pill (Portal · Admin · Partners). The surface renders only the page content (.rs-page), never chrome.

R-4

Visibility is centralized. Internal-note hiding, party filtering and partner scoping are computed inside the component from viewer — never re-implemented per app, so a customer client can never receive a note.

R-5

Layout flags, not layout forks. layout="rail" adds the context rail (Portal/Admin detail); layout="split" drops it (embedded/compact). Both come from the one component.

11.1Responsive

BreakpointBehavior
> 1180pxFull three-column (list · thread · rail) in rail layout; the rail toggles between full Details (300px) and a minimized icon-rail glance at 40px — the collapsed left-sidebar width — every fact an icon + tooltip (persisted).
≤ 1180pxRail hidden; list + thread.
≤ 1024pxCommand-bar identity sub-label + search hide; commands stay.
≤ 900pxCommand labels collapse to icons; list collapses, thread takes over (master-detail).

11.2Accessibility, keyboard & motion

ConcernRequirement
SemanticsList rows are buttons (selected reflected); the thread is a labelled log; the unread dot and presence dot carry text equivalents; status/priority are badge text, not color-only.
Focus3px soft ring (--ring) on :focus-visible; Reply moves focus to the composer textarea; menus close on outside-click / Escape.
ColorCategory, status, priority and note all pair an icon or text with their tint — never color alone.
MotionTyping dots and delivery ticks honor prefers-reduced-motion; no decorative looping.
Hit targetsRows ≥ 38px; command/icon buttons ≥ 40px; composer Send comfortably tappable.
RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 10

12As-built vs production targets

The prototype is the source of truth for look & behavior; these are the deltas a production build must close. None changes the model.

AreaAs-builtProduction target
Partner shellre-tinted pillFirst-class partners portal in AppShell (§10.1).
Typing & presencesimulatedLive presence + typing over the realtime hub.
Read receiptsderived from threadReal per-message delivery/read receipts pushed from the server.
Send / statuslocal statePersist TicketMessage / status, write events, emit domain events.
Quick repliesfixed presetsEditable canned-reply library, per-agent & per-team.
Attachmentsplaceholder cardsReal upload + image lightbox + file download.
Schedulingtoast / cardsLive slot proposal → partner confirm → calendar write.

13Open questions & proposed requirements

14Traceability

This specTraces to
Whole documentPTL-4 (Portal PRD) — tickets as a multi-party support conversation; reused by SPEC-APP-PAR · SPEC-APP-ADM.
Data model (§4)ServiceTicket · TicketMessage (SPEC-ERD-PTL), Support domain (SPEC-DDD-SUP).
Bring-in & agreements (§3.1)Maintenance agreement & partner scope (SPEC-PRD-MNT, SPEC-ERD-PAR).
Process (§9)SPEC-PWF-INC · ticket lifecycle in SPEC-DWF-SUP.
Notes / visibility (§4, §8)Federation roles & tenant visibility (SPEC-PRD-FED).

15Revision history

VersionDateChanges
1.029 Jun 2026First issue — the ticket communication system specified as one reusable surface deployed as a dedicated, viewer-locked page inside each app (no "view as" switcher): Portal (customer) · Admin (RiverSync agent) · Partners (servicing partner). Scope & distinctions (§1–2), the three viewers & partner bring-in (§3), the ServiceTicket/TicketMessage data (§4), layout & grid with annotated wireframe (§5), the context-aware command bar + list/row (§6), thread, parties & the pipeline avatar idiom (§7), communicating in the chat — internal notes, quick replies, attachments, alert cards, scheduling, presence & typing (§8), interactions/states & read receipts (§9), design-system mapping incl. the partners-badge note (§10), reuse rules & responsive (§11), as-built vs target, open questions / proposed requirements, traceability (§12–14). Brought the avatar design and the command-bar navigation from the Pipeline communications system into the ticket surface, and corrected the shared shell brand to the real RiverSync logo/mark vectors. A presentation view over a settled model — no new entities, fields, events or rules; proposed reuse requirement logged. Added to the Design specs family (SPEC-UX-TKT).
RiverSync Co., Ltd. · BangkokSPEC-UX-TKT · 11